added SSCLI 1.0
[windows-sources.git] / shared source / sscli20 / samples / compilers / myc / src / asm.cs
blobdedd9d673cba862e0a613be18ee5e32a32ba3e0b
1 //------------------------------------------------------------------------------
2 // <copyright file="asm.cs" company="Microsoft">
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
13 // </copyright>
14 //------------------------------------------------------------------------------
17 namespace MyC
19 using System;
20 using System.Text;
22 class Asm
24 private Io io;
26 public Asm(Io ihandle)
28 io = ihandle;
32 * determine the IL static type
34 private String ilSType(int type)
36 switch (type)
38 case Tok.T_CHAR: return "char";
39 case Tok.T_SHORT: return "int16";
40 case Tok.T_DEFTYPE:
41 case Tok.T_INT:
42 case Tok.T_LONG: return "int32";
43 case Tok.T_FLOAT: return "float";
44 case Tok.T_DOUBLE: return "double float";
45 case Tok.T_VOID: return "void";
46 default:
47 Console.WriteLine("?Unhandled type " + type);
48 Environment.Exit(1);
49 break;
51 return null;
55 * common routine to construct a signature string for a given varlist item
56 * requires a destination ptr, will return the updated dest ptr
58 private String genDataTypeSig(Var e)
60 if (e == null)
61 return null;
63 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
65 if (e.getSign() == Tok.T_UNSIGNED) /* if var is unsigned, put it in sig */
66 sb.Append("unsigned ");
68 sb.Append(ilSType(e.getTypeId())); /* get the datatype */
69 return (sb.ToString());
72 private String genFieldRef(Var e)
74 if (e == null)
75 return null;
77 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
79 if (e.getSign() == Tok.T_UNSIGNED) /* if var is unsigned, put it in sig */
80 sb.Append("unsigned ");
82 sb.Append(ilSType(e.getTypeId())); /* get the datatype */
83 sb.Append(" ");
84 sb.Append(Io.GetClassname()); /* get the current classname */
85 sb.Append(".");
86 sb.Append(e.getName()); /* copy the variable name */
87 return (sb.ToString());
90 public void Load(IAsm a)
92 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
93 Var e = a.getVar();
94 if (e == null)
96 Console.WriteLine("?Load instruction with no variable ptr");
97 Environment.Exit(1);
99 switch (e.getClassId())
101 case Tok.T_STATIC:
103 sb.Append("\tldsfld ");
104 sb.Append(genFieldRef(e));
105 sb.Append("\t//");
106 sb.Append(a.getICount());
107 sb.Append(", ");
108 sb.Append(e.getName());
109 sb.Append("\r\n");
110 break;
112 case Tok.T_AUTO:
113 case Tok.T_DEFCLASS:
114 sb.Append("\tldloc ");
115 sb.Append(e.getIndex());
116 sb.Append("\t//");
117 sb.Append(a.getICount());
118 sb.Append(", ");
119 sb.Append(e.getName());
120 sb.Append("\r\n");
121 break;
122 case Tok.T_PARAM:
123 sb.Append("\tldarg ");
124 sb.Append(e.getIndex());
125 sb.Append("\t//");
126 sb.Append(a.getICount());
127 sb.Append(", ");
128 sb.Append(e.getName());
129 sb.Append("\r\n");
130 break;
131 default:
132 Console.Write("?Instruction load of unknown class (");
133 Console.Write(e.getClassId());
134 Console.WriteLine(")");
135 Environment.Exit(1);
136 break;
138 io.Out(sb.ToString());
141 public void Store(IAsm a)
143 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
144 Var e = a.getVar();
145 if (e == null)
147 Console.WriteLine("?Store instruction with no variable ptr");
148 Environment.Exit(1);
150 switch (e.getClassId())
152 case Tok.T_STATIC:
153 sb.Append("\tstsfld ");
154 sb.Append(genFieldRef(e));
155 sb.Append("\t//");
156 sb.Append(a.getICount());
157 sb.Append(", ");
158 sb.Append(e.getName());
159 sb.Append("\r\n");
160 break;
161 case Tok.T_AUTO:
162 case Tok.T_DEFCLASS:
163 sb.Append("\tstloc ");
164 sb.Append(e.getIndex());
165 sb.Append("\t//");
166 sb.Append(a.getICount());
167 sb.Append(", ");
168 sb.Append(e.getName());
169 sb.Append("\r\n");
170 break;
171 case Tok.T_PARAM:
172 sb.Append("\tstarg ");
173 sb.Append(e.getIndex());
174 sb.Append("\t//");
175 sb.Append(a.getICount());
176 sb.Append(", ");
177 sb.Append(e.getName());
178 sb.Append("\r\n");
179 break;
180 default:
181 Console.Write("?Instruction load of unknown class (");
182 Console.Write(e.getClassId());
183 Console.WriteLine(")");
184 Environment.Exit(1);
185 break;
187 io.Out(sb.ToString());
190 public void FuncBegin(IAsm a)
192 Var func = a.getVar();
193 String funcsig = genDataTypeSig(a.getVar()); /* gen type info */
195 VarList x = func.getParams(); /* get any params */
196 String paramsig = "";
197 if (x.Length() > 0)
199 int max = x.Length();
200 StringBuilder t = new StringBuilder(MyC.MAXSTR);
201 for (int i = 0; i < max; i++)
203 Var e = x.FindByIndex(i);
204 t.Append(genDataTypeSig(e));
205 if (i < max-1)
206 t.Append(",");
208 paramsig = t.ToString();
210 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
211 sb.Append("\t.method ");
212 sb.Append(funcsig);
213 sb.Append(" ");
214 sb.Append(func.getName());
215 sb.Append("(");
216 sb.Append(paramsig);
217 sb.Append("){\r\n");
218 io.Out(sb.ToString());
220 if (func.getName().Equals("main")) /* special entry point for main */
221 io.Out("\t.entrypoint\r\n");
224 public void Call(IAsm a)
226 Var func = a.getVar();
227 String funcsig = genDataTypeSig(a.getVar()); /* gen type info */
229 VarList x = func.getParams(); /* get any params */
230 String paramsig = "";
231 if (x.Length() > 0)
233 int max = x.Length();
234 StringBuilder t = new StringBuilder(MyC.MAXSTR);
235 for (int i = 0; i < max; i++)
237 Var e = x.FindByIndex(i);
238 t.Append(genDataTypeSig(e));
239 if (i < max-1)
240 t.Append(",");
242 paramsig = t.ToString();
245 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
246 sb.Append("\tcall ");
247 sb.Append(funcsig);
248 sb.Append("(");
249 sb.Append(paramsig);
250 sb.Append(")\t//");
251 sb.Append(a.getICount());
252 sb.Append("\r\n");
253 io.Out(sb.ToString());
256 public void Comment(IAsm a)
258 String sp = a.getComment(); /* source ptr */
259 if (sp == null)
260 return; // empty comment
261 sp.Trim(); // remove extra whitespace
262 if (sp == null || sp.Length == 0) /* sanity check, is there a comment? */
263 return; /* no, then nothing to do */
265 #if DEBUG
266 Console.Write("Comment SP=");
267 for (int _debug_i=0; _debug_i<sp.Length;_debug_i++)
269 int _debug_d = sp[_debug_i];
270 char _debug_c = (char) (_debug_d + 96);
271 if (_debug_d < 32)
272 Console.Write("^"+Char.ToString(_debug_c));
273 else
274 Console.Write(sp[_debug_i]);
275 Console.Write("[");
276 Console.Write(_debug_d);
277 Console.Write("],");
279 Console.WriteLine(";");
280 #endif
281 StringBuilder buf = new StringBuilder(MyC.MAXSTR); /* a buffer to work with */
282 buf.Append("//");
283 buf.Append(a.getCommentLine());
284 buf.Append(": ");
285 int i = 0;
286 int p = 0;
287 while ((i = sp.IndexOf('\n', i)) >= 0)
289 i++; // move past the newline
290 string ts = sp.Substring(p, i-p);
291 String s = ts.Trim();
292 if (s.Length > 0)
293 buf.Append(s); // copy the substr
294 buf.Append("\r\n"); // add the line seperator
295 if (i < sp.Length)
296 buf.Append("//"); // insert the comment block
297 p = i;
300 buf.Append(sp.Substring(p)); // append the remaining chars
301 buf.Append("\r\n");
303 io.Out(buf.ToString()); /* output the comment */
306 public void Insn(IAsm a)
308 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
309 sb.Append("\t");
310 sb.Append(a.getInsn());
311 sb.Append("\t//");
312 sb.Append(a.getICount());
313 sb.Append("\r\n");
314 io.Out(sb.ToString());
317 public void Label(IAsm a)
319 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
320 sb.Append(a.getLabel());
321 sb.Append(":\r\n");
322 io.Out(sb.ToString());
325 public void Branch(IAsm a)
327 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
328 sb.Append("\t");
329 sb.Append(a.getInsn());
330 sb.Append(" ");
331 sb.Append(a.getLabel());
332 sb.Append("\t//");
333 sb.Append(a.getICount());
334 sb.Append("\r\n");
335 io.Out(sb.ToString());
338 public void Ret(IAsm a)
340 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
341 sb.Append("\tret\t\t//");
342 sb.Append(a.getICount());
343 sb.Append("\r\n");
344 io.Out(sb.ToString());
347 public void FuncEnd()
349 io.Out("\t}\r\n");
352 public void LocalVars(VarList v)
354 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
355 sb.Append("\t.locals (");
356 int max = v.Length();
358 for (int i = 0; i < max; i++) // loop thru the local params
360 Var e = v.FindByIndex(i); // indexed by number
361 String stype = "";
362 switch (e.getTypeId())
364 case Tok.T_CHAR: stype = "char"; break;
365 case Tok.T_SHORT: stype = "int16"; break;
366 case Tok.T_INT:
367 case Tok.T_LONG: stype = "int32"; break;
368 case Tok.T_FLOAT: stype = "float"; break;
369 case Tok.T_DOUBLE: stype = "double float"; break;
370 default:
371 Console.WriteLine("?Could not find type for local\n");
372 Environment.Exit(1);
373 break;
375 sb.Append(stype); // append it now
376 if (i < max-1)
377 sb.Append(","); // if not last, seperate with comma
380 sb.Append(")\r\n");
381 io.Out(sb.ToString());
384 public void FieldDef(IAsm a)
386 Var e = a.getVar(); /* get the field var ptr */
387 String prefix = "";
388 switch (e.getClassId())
390 case Tok.T_STATIC:
391 prefix = "\t.field ";
392 break;
393 case Tok.T_AUTO:
394 case Tok.T_DEFCLASS:
395 prefix = "\t.field ";
396 break;
397 default:
398 Console.WriteLine("?Unhandled field def type\n");
399 Environment.Exit(1);
400 break;
403 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
404 sb.Append(prefix); /* copy the prefix */
405 sb.Append(genDataTypeSig(e)); /* gen type info, rets updated dp */
406 sb.Append(" ");
407 sb.Append(e.getName()); /* copy the variable name */
408 sb.Append("\r\n");
409 io.Out(sb.ToString());
412 public void LoadConst(IAsm a)
414 StringBuilder sb = new StringBuilder(MyC.MAXSTR);
415 int value = Convert.ToInt32(a.getInsn());
417 sb.Append("\tldc.i4");
418 if (value > 127 || value < -128) /* if must use long form */
420 sb.Append(" ");
422 else if (value > 8 || value < -1) /* if must use medium form */
424 sb.Append(".s ");
426 else /* else use short form */
428 sb.Append(".");
430 sb.Append(a.getInsn());
431 sb.Append("\t//");
432 sb.Append(a.getICount());
433 sb.Append("\r\n");
435 io.Out(sb.ToString());